package com.sxhalo.fsms.quartz;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sxhalo.fsms.domain.*;

import com.sxhalo.fsms.service.IDeviceLinkageRecordService;
import com.sxhalo.fsms.service.IFactDeviceAlarmRuleService;
import com.sxhalo.fsms.service.IFactDeviceLinkageService;
import com.sxhalo.fsms.socket.WebSocketServer;
import com.sxhalo.fsms.util.DateUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;

@DisallowConcurrentExecution //作业不并发
@Component
public class ScheduledLinkTask implements Job {

	@Autowired
	private RedisTemplate<String, ?> redisTemplate;
	@Autowired
	private IFactDeviceLinkageService LinkageService;
	@Autowired
	private IDeviceLinkageRecordService LinkageRecordService;

	ObjectMapper objectMapper = new ObjectMapper();


	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		// NULL不参与序列化
        objectMapper.setSerializationInclusion(Include.NON_NULL);

		System.out.println("ScheduledLinkTask定时任务" + DateUtil.FormatTime(new Date()));
		//redis 连接失败 如何处理
		try {
			Long startTime = System.currentTimeMillis();
			//查询联动规则
			List<FactDeviceLinkage> linkages=  LinkageService.findWhereList("delete_flag=0 and use_state=1 ","");
			Long runTime = System.currentTimeMillis()-startTime;
			System.out.println(" - [FactDeviceLinkageLinkTask用时, "+(runTime/1000)+"秒] -");
            List<DeviceLinkageRecord> saveLinkageRecord = new ArrayList<DeviceLinkageRecord>();
			//从缓存中读取数据
	        for(FactDeviceLinkage linkage:linkages){
	        	if(linkage.getRules().size()>0&&linkage.getCommands().size()>0){
					if(getLinkagesState(linkage.getRules())){
						saveLinkageRecord(linkage.getCommands(),saveLinkageRecord);
					}
				}
			}
			LinkageRecordService.batchInsert(saveLinkageRecord);
			 runTime = System.currentTimeMillis()-startTime;
			System.out.println(" - [LinkTask用时, "+(runTime/1000)+"秒] -");
			Long runTime1 = System.currentTimeMillis()-startTime;

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(" ---- [redis没连上] ----");
		}
		
		RedisConnectionUtils.unbindConnection(redisTemplate.getConnectionFactory());
		
	}




	private Boolean  getLinkagesState( List<FactDeviceLinkageRule> rules){
		for(FactDeviceLinkageRule rule:rules){
			if((getLinkageItemState(rule)&&rule.getAndOr().equals("or")||rules.size()==1)){
				return true;
			}
			if(!getLinkageItemState(rule)){
				return false;
			}
		}
		return  false;
	}



	private Boolean  getLinkageItemState( FactDeviceLinkageRule rule){
		Boolean linkageState=false;
		Map rowData = redisTemplate.opsForHash().entries(rule.getDeviceId().toString());
		DeviceAttrEnum attrEnum=DeviceAttrEnum.getEnumByKey(rule.getAttrId());
		if(rowData.size()>0&&attrEnum!=null){


			BigDecimal  attrValue=	rowData.get(attrEnum.getMsg())==null?null:new BigDecimal(rowData.get(attrEnum.getMsg()).toString());
			if(rule.getMinValue()!=null&&rule.getMaxValue()!=null){
				if(attrValue.compareTo(new BigDecimal(rule.getMinValue()))==1&&attrValue.compareTo(new BigDecimal(rule.getMaxValue()))==-1){
					linkageState=true;
				}
			}else if(rule.getMinValue()!=null){
				if(attrValue.compareTo(new BigDecimal(rule.getMinValue()))==1){
					linkageState=true;
				}
			}else{
				if(attrValue.compareTo(new BigDecimal(rule.getMaxValue()))==-1){
					linkageState=true;
				}
			}
		}
		return  linkageState;
	}


	private void  saveLinkageRecord( List<FactDeviceLinkageCommand> commands,  List<DeviceLinkageRecord> saveLinkageRecord){
		Timestamp nowtime = new Timestamp(System.currentTimeMillis());
		for(FactDeviceLinkageCommand command:commands ){
			DeviceLinkageRecord linkageRecord=new DeviceLinkageRecord();
			linkageRecord.setCommandId(command.getId());
			linkageRecord.setLinkageId(command.getLinkageId());
			linkageRecord.setDeviceId(command.getDeviceId());
			linkageRecord.setAttrValue(command.getAttrValue());
			linkageRecord.setMessage(command.getMessage());
			linkageRecord.setCreateTime(nowtime);
			linkageRecord.setUpdateTime(nowtime);
			saveLinkageRecord.add(linkageRecord);
		}
	}



}
